use koda_sandbox_manager::{Config, Manager, Result};
use clap::Parser;
use std::path::PathBuf;
use tokio::signal;
use tracing::{info, error};

#[derive(Parser, Debug)]
#[command(name = "koda-sandbox-manager")]
#[command(author, version, about, long_about = None)]
struct Args {
    /// 配置文件路径
    #[arg(short, long, default_value = "config/default.yaml")]
    config: PathBuf,
    
    /// 环境标识 (development/staging/production)
    #[arg(short, long, default_value = "development")]
    environment: String,
    
    /// 覆盖配置文件中的端口设置
    #[arg(short, long)]
    port: Option<u16>,
    
    /// 启用详细日志
    #[arg(short, long)]
    verbose: bool,
}

#[tokio::main]
async fn main() -> Result<()> {
    // 解析命令行参数
    let args = Args::parse();
    
    // 加载配置
    let mut config = if args.config.exists() {
        Config::load_with_overrides(Some(&args.config))?
    } else {
        Config::from_env()?
    };
    
    // 应用命令行覆盖
    config.environment = args.environment;
    if let Some(port) = args.port {
        config.server.port = port;
    }
    if args.verbose {
        config.logging.level = "debug".to_string();
    }
    
    // 创建管理器
    let manager = Manager::new(config.clone()).await?;
    
    info!("Starting Koda Sandbox Manager");
    info!("Environment: {}", config.environment);
    info!("Server listening on {}:{}", config.server.host, config.server.port);
    
    // 启动管理器
    manager.start().await?;
    
    // 启动API服务器
    let manager_clone = manager.clone();
    let api_server = tokio::spawn(async move {
        if let Err(e) = start_api_server(manager_clone.sandbox_manager(), config).await {
            error!("API server failed: {}", e);
        }
    });
    
    // 等待中断信号
    wait_for_signal().await;
    
    info!("Shutting down Koda Sandbox Manager");
    
    // 优雅关闭
    api_server.abort();
    manager.stop().await?;
    
    info!("Koda Sandbox Manager stopped successfully");
    Ok(())
}

async fn start_api_server(
    sandbox_manager: std::sync::Arc<koda_sandbox_manager::SandboxManager>,
    config: Config,
) -> Result<()> {
    use actix_web::{web, App, HttpServer};
    use koda_sandbox_manager::api;
    
    // 创建API状态
    let api_state = api::ApiState::new(sandbox_manager);
    
    // 启动HTTP服务器
    HttpServer::new(move || {
        App::new()
            .app_data(web::Data::new(api_state.clone()))
            .service(api::health_check)
            .service(api::metrics)
            .service(api::acquire_sandbox)
            .service(api::release_sandbox)
            .service(api::execute_code)
    })
    .bind((config.server.host.as_str(), config.server.port))?
    .run()
    .await?;
    
    Ok(())
}

async fn wait_for_signal() {
    let ctrl_c = async {
        signal::ctrl_c()
            .await
            .expect("Failed to install Ctrl+C handler");
    };

    #[cfg(unix)]
    let terminate = async {
        signal::unix::signal(signal::unix::SignalKind::terminate())
            .expect("Failed to install signal handler")
            .recv()
            .await;
    };

    #[cfg(not(unix))]
    let terminate = std::future::pending::<()>();

    tokio::select! {
        _ = ctrl_c => {
            info!("Received Ctrl+C signal");
        },
        _ = terminate => {
            info!("Received terminate signal");
        },
    }
}
